home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
harderr.arc
/
HARDERR.C
next >
Wrap
Text File
|
1991-10-12
|
7KB
|
230 lines
/* HARDERR.C by Bill Buckels 1991 */
/* written in LARGE MODEL MICROSOFT C 5.1 */
/* This program demonstrates the use of a critical error management */
/* Technique Quite Similar to C's own System Error Routines as defined */
/* by the uniform standard in errno.h. */
/* The Error Recovery and Reporting is implemented by a handler written */
/* in assembly language. The reason for this is that the HARD ERRORs */
/* are handled at a fairly low level and C doesn't really offer the */
/* necessary control to implement this type of handler properly. */
/* Bibliography : */
/* The DOS Programmer's Reference 2nd Edition by Que Books provided the */
/* necessary reference for both the DEVICE HEADER (page 339) and the */
/* int 24h critical error handler (page 673). */
/* My testing was less than thorough but all seems to work well enough */
/* and this should give folks a template and a starting point at least. */
/* I am not concerned with other compiler types since Microsoft C is the */
/* Standard For Serious Developers. This will likely work with other */
/* Mixed Language Environments Like Borland but I hardly felt like */
/* Translating my work into a foreign tongue. However... */
/* a possible substitution of MSC functions by TURBO C functions. */
/* I am only guessing... there may be syntatical differences. */
/* also the ASM module may have different rules imposed by TASM and */
/* the ISR declaration may also have semantic differences, etc. */
#ifdef TURBO
#define _far far
#define _dos_setvect setvect
#define _dos_getvect getvect
#define _disable disable
#define _enable enable
#define _exit exit
#endif
#include <stdio.h>
#include <dos.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* a global structure for the hard error info. */
/* theis structure is filled each time our int24 ISR is called */
struct CRIT_ERROR{
unsigned int HARDSTATUS;/* global status flag for Hard Errors */
unsigned int HERRNO; /* global for the last error number */
unsigned int DEVICE_SEG;/* global for the Driver Header Segment */
unsigned int DEVICE_OFF;/* global for the Driver Header Offset */
unsigned char IO_STATUS; /* a DISK I/O status flag */
};
struct CRIT_ERROR crit_error;
/* a new interrupt handler for int 24h */
/* written in assembly language and linked to as an external */
extern interrupt _far int24(void);
#ifndef MK_FP
#define MK_FP(seg,off) ((char _far *)(((long)(seg) << 16) | (off)))
#endif
char *DEVICETEST[]={
"\n\tTHIS IS A TEST OF THE CRITICAL ERROR HANDLER FOR DEVICE I/O.",
"\tTHE PRINTER DEVICE (PRN) IS USED FOR THIS TEST.",
"\tPLEASE MAKE SURE THAT THE PRINTER IS OFF-LINE.",
"\tAND PRESS THE ENTER KEY TO START THE TEST OR ESCAPE TO ABORT.",
NULL};
char *DISKTEST[]={
"\n\tTHIS IS A TEST OF THE CRITICAL ERROR HANDLER FOR DISK I/O.",
"\tPLEASE MAKE SURE THAT THE DRIVE DOOR FOR DRIVE A: IS LEFT OPEN",
"\tAND PRESS THE ENTER KEY TO START THE TEST OR ESCAPE TO ABORT.",
NULL};
main(int argc, char **argv)
{
FILE *fp;
int i;
char c;
puts("\tHarderr by Bill Buckels 1991");
_disable();
/* replace the Hard Error Handler Vector with our own ISR. */
/* when the program terminates this vector is restored */
/* by the system termination handler. */
_dos_setvect(0x24,int24);
_enable();
#define ENTERKEY '\x0d'
/*--------------------| DISK I/O TEST |--------------------*/
for (i=0; DISKTEST[i] != NULL; i++)puts(DISKTEST[i]);
if((c=getch())==ENTERKEY) /* if enter is pressed do the test */
{
/* clear the previous hard error if any */
hardclear();
/* try to open an unlikely file on drive A: */
/* if the Drive Door is Open theis will create a HARD ERROR */
puts("\tNow accessing disk device drive A:");
if((fp=fopen("A:\\$$$$$$$$.$$$","r"))==NULL)
{
hardperror();
}
else
{
fclose(fp);
}
}
if(c=='\x00')c=getch(); /* clear function keys... */
/*--------------------| DEVICE WRITE TEST |--------------------*/
for (i=0; DEVICETEST[i] != NULL; i++)puts(DEVICETEST[i]);
if((c=getch())==ENTERKEY) /* if enter is pressed do the test */
{
hardclear(); /* clear the previous error if any */
puts("\tNow accessing logical device PRN.");
if((fp=fopen("prn","w"))!=NULL)
{
while(!hardperror())fprintf(fp,"Turn The Printer Off.\n");
fclose(fp);
}
else perror("\n\tSTD ERR RE: LOGICAL DEVICE PRN");
}
puts("\nhave a nice DOS!");
_exit(0);
}
/* clear the Hard Error Status Flag */
hardclear()
{
crit_error.HARDSTATUS=FALSE;
}
/* an array of hard error messages */
char *harderrors[]={
/* error code Meaning */
/* (lower byte di) */
/* 00H */ "Write Protect Error",
/* 01H */ "Unknown Unit",
/* 02H */ "Drive Not Ready",
/* 03H */ "Unknown Command",
/* 04H */ "Data Error (BAD CRC)",
/* 05H */ "Bad Request Structure Length",
/* 06H */ "Seek Error",
/* 07H */ "Unknown Media Type",
/* 08H */ "Sector Not Found",
/* 09H */ "Printer Out Of Paper",
/* 0AH */ "Write Fault",
/* 0BH */ "Read Fault",
/* 0CH */ "General Error"};
/* a structure for a device header */
struct DEVICE_HEADER{
unsigned long nextdriver;
unsigned int attribute;
unsigned int strategy_routine;
unsigned int interrupt_routine;
unsigned char device_name[9];
};
/* if there has been a HARD error print the device error */
hardperror()
{
char far *device_ptr;
struct DEVICE_HEADER device_header;
int i;
if(crit_error.HARDSTATUS!=FALSE)
{
if(crit_error.IO_STATUS<128)
{
puts("\n\tHard Error Was Due To Disk I/O");
if(crit_error.HERRNO<0 || crit_error.HERRNO > 0x0c)
puts("\tUnknown Hard Error");
else
printf("\t%s\n",harderrors[crit_error.HERRNO]);
}
else
{
/* point to the header of the device that has failed */
/* then print the device name to the screen. */
device_ptr =MK_FP(crit_error.DEVICE_SEG,crit_error.DEVICE_OFF);
memcpy(&device_header.nextdriver,device_ptr,
sizeof(struct DEVICE_HEADER));
/* replace whitespace with NULLs */
for(i=0;i<8;i++)if(device_header.device_name[i] =='\x20')
device_header.device_name[i] ='\x00';
device_header.device_name[8] ='\x00';
/* terminate ascii Z string */
puts("\n\tHard Error Was not Due To DISK I/O.");
printf("\tError was due to FAILURE of DEVICE %s.\n",
device_header.device_name);
}
}
return crit_error.HARDSTATUS;
}